global class iSalesforceController2 {

	private static final Integer DEFAULT_COLUMN = 0;
	private static final String DEFAULT_TAB = 'home';
	
	private static Map<String, List<List<Gadget__c>>> tabColumnToGadgets;
	private static Map<String, List<UserGadget__c>> tabToUserGadgets;
	private static Map<String, Gadget__c> idToGadget;
	private static UserGadgetTab__c[] userGadgetTabs;
	private static UserGadget__c[] allUserGadgets;
	private static Gadget__c[] allGadgets;

	// cannot seem to have a list of 
	webService static void updateUserGadgets(String encodedGadgets, String tabId)
	{
		loadUserGadgets();	
		
		if ( tabId == '' ) tabId = DEFAULT_TAB;
		
		System.debug('Got column data: '+encodedGadgets);
		
		String[] columns = encodedGadgets.split(';');
		
		Map<String, Integer[]> newGadgetMap = new Map<String, Integer[]>();
		
		Integer i = 0;
		 
		for ( String column : columns )
		{
			Integer j = 0;
			String[] rowz = column.split(',');
			for ( String id : rowz )
			{
				Integer[] pos = new Integer[]{i,j};
				newGadgetMap.put(id, pos);
				System.debug('Added pos for '+id+' ['+i+','+j+']');
				j++;
			}
			i++;
		}
		
		UserGadget__c[] userGadgets = tabToUserGadgets.get(tabId);
		
		if (userGadgets == null) return;
		
		for ( UserGadget__c userGadget : userGadgets)
		{	
			Integer[] pos = newGadgetMap.get(userGadget.Gadget__r.Id);
			System.debug('Getting pos for '+userGadget.Gadget__r.Id);
			userGadget.Column__c = pos.get(0);
			userGadget.Row__c = pos.get(1);
		}
		
		update userGadgets;
		
		return;
	}

	webService static void removeGadget( String gadgetId, String tabId )
	{
		loadUserGadgets();	
		
		if ( tabId == '' ) tabId = DEFAULT_TAB;
		
		System.debug('Getting tab '+tabId);
		
		UserGadget__c[] userGadgets = tabToUserGadgets.get(tabId);
		
		if (userGadgets == null) return;
		
		for ( UserGadget__c userGadget : userGadgets)
		{
			if (userGadget.Gadget__r.Id == gadgetId)
			{
				delete userGadget;
				return;
			}
		}
	}
	
	// cannot seem to have a list of 
	webService static void addGadget(String gadgetId, String tabId)
	{
		
		Gadget__c gadget = [ select Id from Gadget__c where Id=:gadgetId ];
		
		if (gadget == null) return;

		loadUserGadgets();	
		
		if ( tabId == '' ) tabId = DEFAULT_TAB;
		
		System.debug('Getting tab '+tabId);
		
		UserGadget__c[] userGadgets = tabToUserGadgets.get(tabId);
		
		if (userGadgets != null)
		{
			for ( UserGadget__c userGadget : userGadgets)
			{
				if (userGadget.Gadget__r.Id == gadgetId)
				{
					return;
				}
				userGadget.Row__c = userGadget.Row__c == null ? 1 : userGadget.Row__c+1;
			}
	
			update userGadgets;
		}

		UserGadget__c userGadget = new UserGadget__c();
		userGadget.Gadget__c = gadgetId;
		userGadget.User__c = UserInfo.getUserId();
		userGadget.Row__c = 0;
		userGadget.Column__c = 0;
		if ( tabId != null && tabId != DEFAULT_TAB) userGadget.UserGadgetTab__c = tabId;
		insert userGadget;
	}


	// cannot seem to have a list of 
	webService static String addTab(String name)
	{
		UserGadgetTab__c tab = new UserGadgetTab__c();
		tab.name = name;
		insert tab;
		return tab.Id;
	}

	// cannot seem to have a list of 
	webService static void removeTab(String tabId)
	{
		UserGadgetTab__c tab = [ select id, name from UserGadgetTab__c where Id=:tabId];
		if (tab==null) return;
		
		UserGadget__c[] gadgets = [ select id, name from UserGadget__c where UserGadgetTab__c=:tabId];
		
		delete gadgets;
		delete tab;
		
	}

	public String getSessionId()
	{
		return UserInfo.getSessionId();
	}

	public static void loadUserGadgets()
	{

		if (tabColumnToGadgets!=null) return;
		
		tabColumnToGadgets = new Map<String, List<List<Gadget__c>>>();
		tabToUserGadgets = new Map<String, List<UserGadget__c>>();
		idToGadget = new Map<String, Gadget__c>();
		
		String userId = UserInfo.getUserId();
		
		allUserGadgets = [select Id, Row__c, Column__c, Gadget__r.Id, Gadget__r.Name, Gadget__r.Url__c, Gadget__r.Type__c, UserGadgetTab__r.Id from UserGadget__c where User__c=:userId order by Row__c ASC ];
		
		for(UserGadget__c userGadget : allUserGadgets ){ 
			String tabId = userGadget.UserGadgetTab__r.Id == null ? DEFAULT_TAB : userGadget.UserGadgetTab__r.Id;
			Integer column = userGadget.Column__c == null ? DEFAULT_COLUMN : userGadget.Column__c.intValue();
			
			
			
			List<List<Gadget__c>> tab = tabColumnToGadgets.get(tabId);
			if ( tab == null )
			{
				tab = new List<List<Gadget__c>>();
				tabColumnToGadgets.put(tabId, tab);
				tabToUserGadgets.put(tabId, new List<UserGadget__c>());
			}

			List<Gadget__c> gadgets;

			try
			{
				gadgets = tab.get(column);
			}
			catch (Exception e) 
			{
				while (tab.size() <= column)
				{
					tab.add(new List<Gadget__c>());
				}
				
				gadgets = new List<Gadget__c>();
				tab.set(column, gadgets);
				System.debug('Set up tab '+tabId);
			}
			
			gadgets.add(userGadget.Gadget__r);
			tabToUserGadgets.get(tabId).add(userGadget);
			
			
			
			idToGadget.put(userGadget.Gadget__r.Id, userGadget.Gadget__r);
		}
		
	}

	public Gadget__c[] getAllGadgets()
	{	
		
		if ( allGadgets != null) return allGadgets;
		
		allGadgets = [ select Id, Name, Type__c, Url__c from Gadget__c ];
		
		return allGadgets;
	}

	public Map<String, List<List<Gadget__c>>> getUsersGadgets()
	{	
		loadUserGadgets();
		return tabColumnToGadgets;
	}

	public List<List<Gadget__c>> getUsersHomeGadgets()
	{	
		return getUsersGadgets().get(DEFAULT_TAB);
	}
	
	public String getUsersGadgetsJson()
	{	
		
		loadUserGadgets();
		
		String json = '{';
		
		for(String tabId : tabColumnToGadgets.keySet() ){ 
		
			json += tabId + ': [';
		
			List<List<Gadget__c>> columns = tabColumnToGadgets.get(tabId);
			Integer i = 0;
			for(List<Gadget__c> column : columns ){ 
				json += '[';
				for(Gadget__c gadget : column ){ 
					json += '"'+gadget.Id + '",';
				}
				json += '],';
			}
			
			json += '],';
			
		}
		json += '}';
		return json;
	}
	
	public String getAllGadgetsJson()
	{	
		String json = '{';
		for(Gadget__c gadget : getAllGadgets() ){ 
			// need some esc
			json += gadget.Id + ': {  type: "'+gadget.Type__c+'", name: "'+gadget.Name.replace('"','\\"')+'", url: "'+gadget.Url__c+'" },';
		}
		json += '}';
		return json;
	}
	

	public UserGadgetTab__c[] getUserTabs()
	{	
		
		if ( userGadgetTabs != null) return userGadgetTabs;
		
		String userId = UserInfo.getUserId();
		
		userGadgetTabs = [ select Id, Name from UserGadgetTab__c where OwnerId=:userId];
		
		return userGadgetTabs;
	}

	public String getUserTabsJson()
	{	
		String json = '{ home : "Home",';
		for(UserGadgetTab__c utab : getUserTabs() ){ 
			// need some esc
			json += utab.Id + ': "'+utab.Name.replace('"','\\"')+'",';
		}
		json += '}';
		return json;
	}

}